local desc = [[
# 恶魔轮盘玩法简介

一款高风险、高心理博弈的双人或多人轮盘赌对决游戏，玩家在致命赌局中利用道具、欺骗与运气与死神共舞。

## 游戏流程

1.  游戏准备：
    *   使用一把霰弹枪（弹膛容量为10发）；
    *   准备实弹（致命）与空包弹（无害），数量由游戏设定决定（例如4实弹+2空包弹）；
    *   洗混子弹并随机装入弹膛（玩家通常不知道子弹顺序）；
    *   准备道具牌（如放大镜、手锯、香烟、啤酒、手铐等）。
2.  回合流程（玩家轮流行动）：
    *   玩家在自己的回合必须执行以下**一个**主要动作：
        *   **对自己开枪：** 将霰弹枪对准自己头部并扣动扳机
            *   若为**空包弹**：无事发生，**自己获得额外一回合**。
            *   若为**实弹**：扣除一点生命值（初始生命值通常为4点，随游戏人数和轮次增加，至多为6点），轮到对方回合。
        *   **对敌人开枪：** 将霰弹枪对准对手头部并扣动扳机
            *   若为**空包弹**：无事发生，轮到对方回合。
            *   若为**实弹**：对手扣除一点生命值，轮到对方回合。
    *   玩家在自己的回合**可以**执行以下**一个**道具动作（如果持有道具）：
        *   使用一件持有的道具（每件道具效果不同）。
3.  道具系统：
    *   游戏开始或特定回合后会分发道具牌（数量固定或随机）。
    *   道具牌提供扭转局势的能力：
        *   *放大镜：* 查看当前弹膛中的下一发子弹类型。
        *   *手锯：* 使下一次成功命中的实弹伤害增加。
        *   *香烟：* 恢复一点生命值。
        *   *啤酒：* 退出（弹出）当前弹膛内的子弹（不发射）。
        *   *手铐：* 跳过对手的下一个回合（对手不能执行任何动作）。
        *   （其他可能的道具：肾上腺素、一次性手机等）
    *   道具上限为8个，且使用时弃置。
4.  回合结束：
    *   执行完主要动作（和可选的道具动作）后，轮到对手回合。
5.  资源补充：
    *   当霰弹枪空仓后，重新随机装填子弹；并随机分发道具。
6.  胜利条件：
    *   经历三轮游戏，死亡积分最少的玩家获胜。
    
    （每轮第一个死亡的玩家加3分、第二个加2分、第三个加1分）

## 特别说明

*   游戏的核心是**信息差**与**风险决策**：玩家不知道下一发子弹是实弹还是空包弹。
*   使用道具是**关键策略**，能提供信息、改变伤害、恢复生命或干扰对手。
*   **对敌人开枪**成功命中（实弹）会获得额外回合，这是高风险高回报的激进策略。
*   生命值是有限的资源，管理生命和利用道具是生存的关键。
*   第一轮随机玩家获得先手，其后每一轮，由上一轮最先死亡的玩家先手。
]]
-- 轮次
---@param room Room
local function rouletteGame_Round(room)

    --更新轮次
    local roundCount = room:getTag("RoundCount") or 0
    roundCount = roundCount + 1
    room:setTag("RoundCount",  roundCount)
    room:doBroadcastNotify("UpdateRoundNum", roundCount)

    local current = room:getBanner("dead_player") or table.random(room.alive_players)
    room:setBanner("dead_player",nil)
    room:setBanner("demons",{})

    --更新角色
    for _, p in ipairs(room.players) do
        local num = 4
        num = num + #room.players - 2
        num = num + roundCount - 1
        num = math.min(6,num)
        room:setPlayerProperty(p, "maxHp", num)
        room:setPlayerProperty(p, "hp", p.maxHp)
        room:broadcastProperty(p,"maxHp")
        room:broadcastProperty(p,"hp")
        room:moveCardTo(p:getCardIds("h"), Card.DrawPile, nil, fk.ReasonJustMove, nil, nil, false)
    end

    while #room.alive_players > 1 do
        if not room:getBanner("demons") or #room:getBanner("demons") == 0 then
            local demos = {}
            local maxDemos = math.random(2,not room:getBanner("demons") and 6 or 10)
            local drawNums = math.random(2, 4 + roundCount + (not room:getBanner("demons") and 0 or 1) )
            for _ = 1, maxDemos, 1 do
                if math.random() > 0.5 then
                    table.insert(demos,1)
                else
                    table.insert(demos,0)
                end
            end
            room:shuffleDrawPile()
            for _, cp in ipairs(room.alive_players) do
                room:setPlayerMark(cp,"@@roulette_handcuffs_skill",0)
                if (8 - #cp.player_cards[Player.Hand]) > 0 and math.min(8 - #cp.player_cards[Player.Hand],drawNums) > 0 then
                    cp:drawCards(math.min(8 - #cp.player_cards[Player.Hand],drawNums))
                end
                --[[if p and p:getHandcardNum() > 8 then
                    local discardNum = p:getHandcardNum() - 8
                    local cards = room:askToDiscard(p,{
                        max_num = discardNum,
                        min_num = discardNum,
                        skill_name = "discard_skill",
                        cancelable = false,
                        include_equip = false,
                        pattern = ".",
                        prompt = "#rouletteGame-Discard",
                        skip = true,
                    })
                    room:moveCardTo(cards, Card.DiscardPile, nil, fk.ReasonDiscard, nil, nil, false)
                end]]--
            end
            room:setBanner("demons",demos)
            room:sendLog{
                type = "#RouletteStart",
                arg = "<font color='#CC3131'>"..#table.filter(demos,function (element) return element == 1 end).."</font>",
                arg2 = #table.filter(demos,function (element) return element == 0 end),
                toast = true,
            }
            room:broadcastPlaySound("./packages/water_wegame/audio/effect/shotgun_load")
            room:delay(2000)
        end

        room:setCurrent(current)

        if current:getMark("@@roulette_handcuffs_skill") > 0 then
            room:setPlayerMark(current,"@@roulette_handcuffs_skill",0)
            current = current:getNextAlive()
        else
            local target = nil
            while not target and room:getBanner("demons") and #room:getBanner("demons") > 0 and current.hp > 0 do
                --ai策略
                if current.id > 0 then
                    local bool, dat = room:askToUseActiveSkill(current,{
                        skill_name = "#roulette_active&",
                        prompt = "#rouletteGame",
                        cancelable = false,
                        skip = true,
                    })
                    if bool and dat then
                        if #dat.cards > 0 then
                            local tos = {current}
                            if #dat.targets > 0 then
                                tos = dat.targets
                            end
                            room:useCard{
                                from = current,
                                card = Fk:getCardById(dat.cards[1]),
                                tos = tos,
                            }
                            --使用胶囊可能会死，判一下
                            if current.hp < 1 then
                                room:addPlayerMark(current,"roulette_score",#room.alive_players - 1)
                                if not room:getBanner("dead_player") then room:setBanner("dead_player",current) end
                                room:setPlayerProperty(current, "dead", true)
                                current._splayer:setDied(true)
                                table.removeOne(room.alive_players, current)
                            end
                        else
                            target = dat.targets[1]
                        end
                    end
                else
                    room:notifyMoveFocus(current,"#roulette_active&")
                    room:delay(1000)
                    local cards = current.player_cards[Player.Hand]
                    local used = false
                    --如果没血，优先使用回血道具
                    if current.hp < current.maxHp then
                        for _, cardName in ipairs({"roulette_medicine","roulette_cigarette"}) do
                            if current.hp > 0 and not used then
                                local cs = table.filter(cards,function (cardID)
                                    local tempc = Fk:getCardById(cardID)
                                    return tempc.name == cardName and current:canUseTo(tempc,current)
                                end)
                                if #cs > 0 then
                                    used = true
                                    room:useCard{ from = current, card = Fk:getCardById(table.random(cs)), tos = {current} }
                                    if current.hp < 1 then
                                        room:addPlayerMark(current,"roulette_score",#room.alive_players - 1)
                                        if not room:getBanner("dead_player") then room:setBanner("dead_player",current) end
                                        room:setPlayerProperty(current, "dead", true)
                                        current._splayer:setDied(true)
                                        table.removeOne(room.alive_players, current)
                                    end
                                end
                            end
                        end
                    end
                    if current.hp > 0 and not used then
                        --优先使用肾上腺素
                        for _, cardID in ipairs(cards) do
                            local tempc = Fk:getCardById(cardID)
                            if tempc.name == "roulette_adrenaline" and not used then
                                for _, tp in ipairs(room.alive_players) do
                                    if current:canUseTo(tempc,tp) and not used then
                                        used = true
                                        room:useCard{ from = current, card = tempc, tos = {tp} }
                                    end
                                end
                            end
                        end
                    end
                    if current.hp > 0 and not used then
                        --其次使用手铐
                        for _, cardID in ipairs(cards) do
                            local tempc = Fk:getCardById(cardID)
                            if tempc.name == "roulette_handcuffs" and not used then
                                for _, tp in ipairs(room.alive_players) do
                                    if current:canUseTo(tempc,tp) and not used then
                                        used = true
                                        room:useCard{ from = current, card = tempc, tos = {tp} }
                                    end
                                end
                            end
                        end
                    end
                    if current.hp > 0 and not used and (not room:getBanner("@@roulette_handsaw") or room:getBanner("@@roulette_handsaw") == 0) then
                        --未使用手锯时，随机使用放大镜和逆转器
                        for _, cardName in ipairs({"roulette_magnifier","roulette_reverser"}) do
                            if current.hp > 0 and not used then
                                local cs = table.filter(cards,function (cardID)
                                    local tempc = Fk:getCardById(cardID)
                                    return tempc.name == cardName and current:canUseTo(tempc,current)
                                end)
                                if #cs > 0 and math.random() > 0.6 then
                                    used = true
                                    room:useCard{ from = current, card = Fk:getCardById(table.random(cs)), tos = {current} }
                                end
                            end
                        end
                    end
                    if current.hp > 0 and not used and room:getBanner("demons") and #room:getBanner("demons") > 1 and (not room:getBanner("@@roulette_handsaw") or room:getBanner("@@roulette_handsaw") == 0) then
                        --未使用手锯时，子弹大于1枚时随机使用啤酒
                        for _, cardID in ipairs(cards) do
                            local tempc = Fk:getCardById(cardID)
                            if tempc.name == "roulette_beer" and not used and current:canUseTo(tempc,current) and math.random() > 0.5 then
                                used = true
                                room:useCard{ from = current, card = tempc, tos = {current} }
                            end
                        end
                    end
                    if current.hp > 0 and not used and room:getBanner("demons") and #room:getBanner("demons") > 2 then
                        --子弹大于2枚时随机使用手机
                        for _, cardID in ipairs(cards) do
                            local tempc = Fk:getCardById(cardID)
                            if tempc.name == "roulette_telephone" and not used and current:canUseTo(tempc,current) and math.random() > 0.5 then
                                used = true
                                room:useCard{ from = current, card = tempc, tos = {current} }
                            end
                        end
                    end
                    if current.hp > 0 and not used and room:getBanner("demons") and #room:getBanner("demons") > 0 and room:getBanner("demons")[1] == 1 then
                        --当前为实弹时，随机使用手锯
                        for _, cardID in ipairs(cards) do
                            local tempc = Fk:getCardById(cardID)
                            if tempc.name == "roulette_handsaw" and not used and current:canUseTo(tempc,current) and math.random() > 0.5 then
                                used = true
                                room:useCard{ from = current, card = tempc, tos = {current} }
                            end
                        end
                    end
                    if current.hp > 0 and not used then
                        --使用手锯后或仅剩实弹不打自己，仅剩空弹打自己，剩余都是随机开枪
                        if (room:getBanner("@@roulette_handsaw") and room:getBanner("@@roulette_handsaw") ~= 0) or (#room:getBanner("demons") == 1 and room:getBanner("demons")[1] == 1) then
                            target = table.random(table.filter(room.alive_players,function (cp)
                                return cp ~= current
                            end))
                        elseif #room:getBanner("demons") == 1 and room:getBanner("demons")[1] == 0 then
                            target = current
                        else
                            target = table.random(room.alive_players)
                        end
                    end
                end
            end
            if target and room:getBanner("demons") and #room:getBanner("demons") > 0 then
                room:doIndicate(current,{target})
                local demos = room:getBanner("demons")
                local demo = table.remove(demos,1)
                local damageNum = 1
                if room:getBanner("@@roulette_handsaw") and room:getBanner("@@roulette_handsaw") ~= 0 then
                    damageNum = 2
                    room:setBanner("@@roulette_handsaw",0)
                end
                local logDemo = {"空弹","<font color='#CC3131'>实弹</font>"}
                room:sendLog{
                    type = "#RouletteShoot",
                    from = current.id,
                    to = {target.id},
                    arg = logDemo[demo + 1],
                    toast = true,
                }
                if demo == 1 then
                    room:broadcastPlaySound("./packages/water_wegame/audio/effect/shotgun")
                    room:setPlayerProperty(target, "hp", target.hp - damageNum)
                    room:delay(500)
                    if target.hp < 1 then
                        room:addPlayerMark(target,"roulette_score",#room.alive_players - 1)
                        if not room:getBanner("dead_player") then room:setBanner("dead_player",target) end
                        room:setPlayerProperty(target, "dead", true)
                        target._splayer:setDied(true)
                        table.removeOne(room.alive_players, target)
                    end
                end
                room:setBanner("demons",demos)
                if target ~= current or demo == 1 then
                    current = current:getNextAlive()
                end
            else
                current = current:getNextAlive()
            end
        end
    end

    --更新角色
    if roundCount < 3 then
        for _, p in ipairs(room.players) do
            if not p:isAlive() then
                if not p.dead then return end
                room:setPlayerProperty(p, "dead", false)
                p._splayer:setDied(false)
                room:setPlayerProperty(p, "dying", false)
                table.insertIfNeed(room.alive_players, p)
                room:updateAllLimitSkillUI(p)
            end
        end
    else
        local players = table.simpleClone(room.players)
        table.sort(players, function(p1, p2)
            return p1:getMark("roulette_score") < p2:getMark("roulette_score")
        end)
        local scores = table.map(players, function(p) return p:getMark("roulette_score") end)
        local roles = {"lord","loyalist","rebel","renegade"}
        for index, cp in ipairs(players) do
            room:setPlayerProperty(cp, "role", scores[index] == scores[1] and "lord" or roles[index])
        end
        --room:setPlayerProperty(room.alive_players[1], "role", "lord")
        room:sendLog{
            type = "#RouletteGameOver",
            arg = players[1]._splayer:getScreenName(),
            toast = true,
        }
        room:gameOver("lord")
    end

end
-- 主游戏逻辑
---@param room Room
local function rouletteGame(room)
    room:setBanner("@roulette_game","恶魔轮盘"..(#room.players > 2 and " 多人模式" or ""))
    local roundCount = room:getTag("RoundCount") or 0
    while roundCount < 3 and #room.alive_players > 1 do
        room:delay(500)
        rouletteGame_Round(room)
    end
    -- 游戏结束
    if roundCount >= 3 and #room.alive_players == 1 then
        local players = table.simpleClone(room.players)
        table.sort(players, function(p1, p2)
            return p1:getMark("roulette_score") < p2:getMark("roulette_score")
        end)
        local scores = table.map(players, function(p) return p:getMark("roulette_score") end)
        local roles = {"lord","loyalist","rebel","renegade"}
        for index, cp in ipairs(players) do
            room:setPlayerProperty(cp, "role", scores[index] == scores[1] and "lord" or roles[index])
        end
        --room:setPlayerProperty(room.alive_players[1], "role", "lord")
        room:sendLog{
            type = "#RouletteGameOver",
            arg = players[1]._splayer:getScreenName(),
            toast = true,
        }
        room:gameOver("lord")
    end
end
-- 游戏逻辑
local function logic()
    ---@class rouletteLogic: GameLogic
    local rouletteLogic = GameLogic:subclass("rouletteLogic")
    function rouletteLogic:chooseGenerals()
        local room = self.room
        for _, p in ipairs(room.players) do
            local avatar = p._splayer:getAvatar()
            if avatar == "anjiang" then
                avatar = table.random{"blank_shibing", "blank_nvshibing"}
            end
            local general = Fk.generals[avatar] or Fk.generals["diaochan"]
            --ai随机选将
            if p.id < 0 then
                local generals = {}
                for key, value in pairs(Fk.generals) do
                    table.insert(generals,key)
                end
                general = Fk.generals[table.random(generals)]
            end
            room:setPlayerProperty(p, "general", general.name)
            room:setPlayerProperty(p, "kingdom", general.kingdom)
            room:setPlayerProperty(p, "role", p._splayer:getScreenName())
            room:setPlayerProperty(p, "role_shown", true)
        end
    end
    function rouletteLogic:broadcastGeneral() end
    function rouletteLogic:attachSkillToPlayers()
        local room = self.room
        for _, p in ipairs(room.players) do
            room:handleAddLoseSkills(p, "#roulette_rule&", nil, false)
        end
    end
    function rouletteLogic:prepareForStart() end
    function rouletteLogic:action()
        rouletteGame(self.room)
    end
    return rouletteLogic
end

-- 创建游戏模式
local mode = fk.CreateGameMode {
    name = "roulette_game",
    minPlayer = 2,
    maxPlayer = 4,
    logic = logic,
    whitelist = {
      "water_wegame_roulette_mode"
    }
}

-- 加载翻译
Fk:loadTranslationTable {
  ["roulette_game"] = "恶魔轮盘",
  [":roulette_game"] = desc,
  -- 日志翻译
  ["#RouletteStart"] = "本轮枪内有 %arg 发实弹 %arg2 发空弹",
  ["#RouletteShoot"] = "%from 选择对 %to 开枪，结果是 %arg",
  ["#RouletteGameOver"] = "游戏结束！%arg 获得了胜利！",
  -- 提示信息
  ["#rouletteGame-Discard"] = "请弃置多余牌",
  ["#rouletteGame"] = "对一名角色开枪，或使用一张牌",
  ["@roulette_game"] = "",
}

return mode